/*
 * Copyright (c) Jack魏 2023 - 2023, All Rights Reserved.
 */

package cn.jack1996.yiyi.util;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.RegisteredPayload;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;

/**
 * Jwt封装工具类
 *
 * @author Jack魏
 * @since 2023/2/17 22:51
 */
@Component
public class JwtUtil {
    /**
     * 生成token的密码
     */
    private static String tokenKey;
    /**
     * 负载信息加密秘钥
     */
    private static String payloadKey;
    /**
     * token过期时长（秒）
     */
    private static int TIME_OUT_SECOND = 60 * 60 * 24 * 30;
    /**
     * 去除前缀
     */
    private static final String BEARER = "Bearer ";

    /**
     * 静态字段不能使用@Value注解，必须要这样中转一下（注意set这里不能加static）
     *
     * @param tokenKey 生成token的密码
     */
    @Value("${yiyi.password.jwt.token}")
    public void setTokenKey(String tokenKey) {
        JwtUtil.tokenKey = tokenKey;
    }

    /**
     * 静态字段不能使用@Value注解，必须要这样中转一下（注意set这里不能加static）
     *
     * @param payloadKey 负载信息加密秘钥
     */
    @Value("${yiyi.password.jwt.payload}")
    public void setPayloadKey(String payloadKey) {
        JwtUtil.payloadKey = payloadKey;
    }

    /**
     * 创建token
     *
     * @param payload 负载信息
     * @return token信息
     */
    public static String getToken(Map<String, Object> payload) {
        Date now = DateTime.now();
        //签发时间，当前时间
        payload.put(RegisteredPayload.ISSUED_AT, now);
        //过期时间
        payload.put(RegisteredPayload.EXPIRES_AT, DateUtil.offsetSecond(now, TIME_OUT_SECOND));
        //生效时间，立即生效
        payload.put(RegisteredPayload.NOT_BEFORE, now);

        // 签名秘钥
        JWTSigner jwtSigner = JWTSignerUtil.hs512(tokenKey.getBytes(StandardCharsets.UTF_8));
        return JWTUtil.createToken(payload, jwtSigner);
    }

    /**
     * 验证token
     *
     * @param token token值
     * @return 异常信息
     */
    public static String verify(String token) {
        if (CharSequenceUtil.isEmpty(token)) {
            return "令牌为空，请重新登录!";
        }
        if (!CharSequenceUtil.startWith(token, BEARER)) {
            return "令牌类型错误，请重新登录!";
        }
        token = token.substring(BEARER.length());
        JWTSigner jwtSigner = JWTSignerUtil.hs512(tokenKey.getBytes(StandardCharsets.UTF_8));
        if (!JWTUtil.verify(token, jwtSigner)) {
            return "令牌错误，请重新登录!";
        }
        JWT jwt = JWTUtil.parseToken(token);
        // 有没有超时
        final boolean validate = jwt.setKey(tokenKey.getBytes(StandardCharsets.UTF_8)).validate(0);
        if (!validate) {
            return "令牌超时， 请重新登录!";
        }
        return "";
    }

    /**
     * 根据token获取存储的值
     *
     * @param token token值
     * @param name 需要获取的名称
     * @return 负载值
     */
    public static Object getClaim(String token, String name) {
        JWT jwt = JWTUtil.parseToken(token.substring(BEARER.length()));
        return jwt.getPayload().getClaim(name);
    }
}
